package com.fingard.dsp.bank.directbank.cfcc01;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.db.JDBCHelper;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.reqrespobj.RequestBase;
import com.fingard.dsp.bank.reqrespobj.single.*;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.net.ConnState;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.sql.Connection;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

/**
 * @author Parker on 2019-08-13.
 * @version 1.0
 */
public class CFCC01SinglePay extends CFCC01Base implements ISinglePay {

    @Override
    public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1908.reqHeader);
        //跨行转账, 又分普通跨行和超级网银跨行, 通过判断条件判断是否需要超级网银转账
        if (isNetPay(p_req1908)) {
            return d_1908_NetPay(retAts, p_req1908);
        } else {
            return d_1908_Pay(retAts, p_req1908);
        }
    }

    /**
     * 行内,跨行,转账
     *
     * @param retAts
     * @param p_req1908
     * @return
     */
    public RetAtsSingle d_1908_Pay(RetAtsSingle retAts, ReqSingle p_req1908) throws Exception {
        XmlTextWriter xmlWriter = new XmlTextWriter();
        try {
            CFCC01Header bankHeader = new CFCC01Header();
            bankHeader.transCode = "payment";
            writeCommonHeader(xmlWriter, bankHeader);
            xmlWriter.writeStartElement("REQUEST");
            xmlWriter.writeElementString("CHANNEL", "ERP");
            xmlWriter.writeElementString("PAYACCTNO", p_req1908.singleDetail.payAct);
            xmlWriter.writeElementString("RECACCTNAME", p_req1908.singleDetail.recName);
            xmlWriter.writeElementString("RECACCTNO", p_req1908.singleDetail.recAct);
            xmlWriter.writeElementString("RECORGNAME", p_req1908.singleDetail.recBankLocation);//收款方开户行名称
            xmlWriter.writeElementString("PROVINCENAME", p_req1908.singleDetail.getOppProvinceAndCity()[0]);//收方账户开户行所在省
            xmlWriter.writeElementString("CITYNAME", p_req1908.singleDetail.getOppProvinceAndCity()[1]);//收方账户开户行所在市
            xmlWriter.writeElementString("RECBANKNAME", p_req1908.singleDetail.recBankName);
            xmlWriter.writeElementString("TRANAMT", p_req1908.singleDetail.payAmount);
            xmlWriter.writeElementString("PAYMODE", "2");//2-电汇
            if ("1".equals(p_req1908.singleDetail.sameBnk)) {
                xmlWriter.writeElementString("TRANTYPE", "201");
            } else {
                xmlWriter.writeElementString("TRANTYPE", "203");
            }
            xmlWriter.writeElementString("URGFLAG", "1".equals(p_req1908.singleDetail.paySpd) ? "1" : "0");//是否加急 1加急
            xmlWriter.writeElementString("EXPLMODE", "2");//2-代理支付
            xmlWriter.writeElementString("TRANDATE", Format.Date8Format.format(Format.Date8Format.parse(p_req1908.singleDetail.payDate)));
            xmlWriter.writeElementString("DIGEST", p_req1908.singleDetail.description);//摘要
            xmlWriter.writeElementString("VOUCHER_ID", p_req1908.reqHeader.transSeqID);//指令ID
            xmlWriter.writeElementString("CUSTID", bankFront.org);//客户编号
            xmlWriter.writeElementString("APPROVALPROCESS", getBankConfig().getValueAsString("approvalProcess"));//是否审批:0:不走审批，1:走审批
            xmlWriter.writeElementString("USERNAME", "");//财务公司企业网银经办员登录名 走审批必输
            xmlWriter.writeEndElement();
            xmlWriter.writeEndDocument();
            retAts = sendPayBank(retAts, xmlWriter.toXmlString(), p_req1908);
        } catch (Exception e) {
            retAts.writeRespCode("-1");
            retAts.writeRespInfo(e.getMessage());
        }
        return retAts;
    }

    /**
     * 超级网银对外付款
     *
     * @param retAts
     * @param p_req1908
     * @return
     */
    public RetAtsSingle d_1908_NetPay(RetAtsSingle retAts, ReqSingle p_req1908) throws Exception {
        XmlTextWriter xmlWriter = new XmlTextWriter();
        try {
            CFCC01Header bankHeader = new CFCC01Header();
            bankHeader.transCode = "supBeankPay";
            writeCommonHeader(xmlWriter, bankHeader);
            xmlWriter.writeStartElement("REQUEST");
            xmlWriter.writeElementString("CUSTID", bankFront.org);//客户号
            xmlWriter.writeElementString("PAYACCTNO", p_req1908.singleDetail.payAct);
            xmlWriter.writeElementString("PAYACCTNAME", p_req1908.singleDetail.payName);
            xmlWriter.writeElementString("PAYBRANCHNAME", p_req1908.singleDetail.payBankLocation);
            xmlWriter.writeElementString("TRANTYPE", "205");
            xmlWriter.writeElementString("CCY", convertCurToBank(p_req1908.singleDetail.payCur));
            xmlWriter.writeElementString("RECACCTNAME", p_req1908.singleDetail.recName);
            xmlWriter.writeElementString("RECACCTNO", p_req1908.singleDetail.recAct);
            xmlWriter.writeElementString("RECORGID", p_req1908.singleDetail.recBankLocation);
            xmlWriter.writeElementString("RECBRANCHID", p_req1908.singleDetail.cnapsName);//CNAPS
            xmlWriter.writeElementString("TRANAMT", p_req1908.singleDetail.payAmount);
            xmlWriter.writeElementString("URGFLAG", "1".equals(p_req1908.singleDetail.paySpd) ? "1" : "0");//是否加急 1加急
            xmlWriter.writeElementString("TRANDATE", Format.Date8Format.format(Format.Date8Format.parse(p_req1908.singleDetail.payDate)));//交易时间
//            xmlWriter.writeElementString("provincename", p_req1908.singleDetail.getOppProvinceAndCity()[0]);//收方账户开户行所在省
//            xmlWriter.writeElementString("cityname", p_req1908.singleDetail.getOppProvinceAndCity()[1]);//收方账户开户行所在市
            xmlWriter.writeElementString("PAYUSE", p_req1908.singleDetail.askNumber);
            xmlWriter.writeElementString("CHANEL", "ERP");
            xmlWriter.writeElementString("VOUCHER_ID", p_req1908.reqHeader.transSeqID);
            xmlWriter.writeElementString("APPROVALPROCESS", getBankConfig().getValueAsString("approvalProcess"));//是否审批:0:不走审批，1:走审批
            xmlWriter.writeElementString("USERNAME", "");//财务公司企业网银经办员登录名 走审批必输
            xmlWriter.writeEndElement();
            xmlWriter.writeEndDocument();
            retAts = sendPayBank(retAts, xmlWriter.toXmlString(), p_req1908);
        } catch (Exception e) {
            retAts.writeRespCode("-1");
            retAts.writeRespInfo(e.getMessage());
        }
        return retAts;
    }

    /**
     * 发送银行, 解析支付结果
     *
     * @param retAts
     * @param p_req1908
     * @return
     * @throws Exception
     */
    private RetAtsSingle sendPayBank(RetAtsSingle retAts, String sendBank, ReqSingle p_req1908) throws Exception {
        RetAtsSglDetail retDetail = new RetAtsSglDetail();
        Connection conn = FGBiz.getLocalDbConn();
        try {
            String[] tmpRetBkStr = sendToBank(sendBank);
            if (tmpRetBkStr[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetBkStr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String returnCode = tmpBkReader.getFirstText("/TRANSACTION/HEADER/REP_CODE");
                    String returnMsg = tmpBkReader.getFirstText("/TRANSACTION/HEADER/REP_DESC");
                    if (returnCode != null && returnCode.equals("0000")) {
                        retDetail.respCode = "0";
                        retDetail.respInfo = returnMsg;
                        retDetail.payInfoCode = returnCode;
                        retDetail.transState = returnCode;
                        retDetail.transAmt = p_req1908.singleDetail.payAmount;
                        retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                        //记录银行返回流水号,支付指令编号,流程实例号，供查询状态接口使用
                        //通过判断条件判断是否是超级网银转账
                        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                        String sql = "INSERT INTO REQSEQIDMAPPING(URID,BANKCODE,TRANSDATE,REQSEQID,BANKREQSEQID) values (?,?,?,?,?);";
                        if (isNetPay(p_req1908)) {
                            JDBCHelper.update(conn, sql, new Object[]{uuid, p_req1908.reqHeader.bankCode, Format.Date8Format.format(new Date()), p_req1908.singleDetail.askNumber, tmpBkReader.getFirstText("/TRANSACTION/RESPONSE/TRANNO")});
                        } else {
                            JDBCHelper.update(conn, sql, new Object[]{uuid, p_req1908.reqHeader.bankCode, Format.Date8Format.format(new Date()), p_req1908.singleDetail.askNumber, tmpBkReader.getFirstText("/TRANSACTION/RESPONSE/CMSTRANNO")});
                        }
                    } else {
                        retDetail.respCode = "-1";
                        retDetail.respInfo = returnMsg;
                    }
                } else {
                    retDetail.respCode = "-1";
                    retDetail.respInfo = tmpSbMsg.toString();
                }
            } else if (tmpRetBkStr[0].equals(ConnState.FAIL)) {
                retDetail.respCode = "0";
                retDetail.respInfo = tmpRetBkStr[1];
                retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                retDetail.transState = PaymentState.FAIL_Payment;
                retDetail.payInfoCode = tmpRetBkStr[0];
            } else {
                retDetail.respCode = "-1";
                retDetail.respInfo = tmpRetBkStr[1];
                retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
            }
        } catch (Exception e) {
            retAts.writeRespCode("-1");
            retAts.writeRespInfo(e.getMessage());
        } finally {
            if (conn != null) {
                conn.close();
            }
        }
        retAts.writeRetDetail(retDetail);
        return retAts;
    }

    @Override
    public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail retDetail = new RetAtsSglDetail();
        Connection conn = FGBiz.getLocalDbConn();
        try {
            String transId = "";
            String sql = "SELECT BANKREQSEQID FROM REQSEQIDMAPPING WHERE REQSEQID=? AND BANKCODE=?;";
            Map<String, Object> selMap = JDBCHelper.execQuerySingle(conn, sql, new Object[]{p_req1944.askNumber, p_req1944.reqHeader.bankCode});
            if (selMap.size() > 0) {
                transId = selMap.get("BANKREQSEQID").toString();
            } else {
                retDetail.respCode = "-1";
                retDetail.respInfo = "交易流水号关联映射异常，请检查";
                retAts.writeRetDetail(retDetail);
                return retAts;
            }
            XmlTextWriter xmlWriter = new XmlTextWriter();
            CFCC01Header bankHeader = new CFCC01Header();
            if (isNetPay(p_req1944)) {
                bankHeader.transCode = "supBeankPayStatusQuery";
                writeCommonHeader(xmlWriter, bankHeader);
                xmlWriter.writeStartElement("REQUEST");
                xmlWriter.writeElementString("CUSTID", bankFront.org);//客户号
                xmlWriter.writeElementString("TRANNO", transId);//
            }else{
                bankHeader.transCode = "paymentStatusQuery";
                writeCommonHeader(xmlWriter, bankHeader);
                xmlWriter.writeStartElement("REQUEST");
                xmlWriter.writeElementString("CMSTRANNO", transId);//
            }
            xmlWriter.writeEndElement();
            xmlWriter.writeEndDocument();
            String[] tmpRetBkStr = sendToBank(xmlWriter.toXmlString());
            if (tmpRetBkStr[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetBkStr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String returnCode = tmpBkReader.getFirstText("/TRANSACTION/HEADER/REP_CODE");
                    String returnMsg = tmpBkReader.getFirstText("/TRANSACTION/HEADER/REP_DESC");
                    if(returnCode != null && ("true".equals(returnCode) || "0000".equals(returnCode))){
                        retDetail.respCode = "0";
                        retDetail.respInfo = returnMsg;
                        retDetail.transAmt = p_req1944.payAmount;
                        if (isNetPay(p_req1944)) {
                            retDetail.payInfoCode = returnCode + "+" + tmpBkReader.getFirstText("/TRANSACTION/RESPONSE/STATUS");
                            retDetail.transState = retDetail.payInfoCode;
                        } else {
                            retDetail.payInfoCode = returnCode + "+" + tmpBkReader.getFirstText("/TRANSACTION/RESPONSE/TRANSTAT");
                            retDetail.transState = retDetail.payInfoCode;
                        }
                    }else{
                        retDetail.respCode = "-1";
                        retDetail.respInfo = returnMsg;
                    }
                } else {
                    retDetail.respCode = "-1";
                    retDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                retDetail.respCode = "-1";
                retDetail.respInfo = tmpRetBkStr[1];
            }
        } catch (Exception e) {
            retDetail.respCode = "-1";
            retDetail.respInfo = e.getMessage();
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.close();
            }
        }
        retAts.writeRetDetail(retDetail);
        return retAts;
    }

    /**
     * 判断是否启用超级网银支付
     *
     * @param p_req
     * @return
     */
    private boolean isNetPay(RequestBase p_req) {
        return getBankConfig().getValueAsBool("isNetPay");
    }


    @Override
    public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception {
        return null;
    }

    @Override
    public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception {
        return null;
    }
}
